# -*- coding: utf-8 -*-
# @Time    : 2024/7/26 15:07
# @Author  : yujiahao
# @File    : 62_fastapi_use_request.py
# @description:直接使用请求


"""
1. 直接使用请求：
   - 我们已经使用多种类型声明了请求的各种组件，并从以下对象中提取数据：
     - 路径参数
     - 请求头
     - Cookies
     - 等

2. FastAPI 的数据处理：
   - FastAPI 使用这种方式验证数据、转换数据，并自动生成 API 文档。

3. 直接访问 Request 对象：
   - 有时，我们需要直接访问 Request 对象。

4. Request 对象的细节：
   - FastAPI 的底层是 Starlette，FastAPI 只不过是在 Starlette 顶层提供了一些工具，所以能直接使用 Starlette 的 Request 对象。
   - 直接从 Request 对象提取数据时（例如，读取请求体），FastAPI 不会验证、转换和存档数据（为 API 文档使用 OpenAPI）。
   - 不过，仍可以验证、转换与注释（使用 Pydantic 模型的请求体等）其它正常声明的参数。
   - 在某些特定情况下，还是需要提取 Request 对象。
"""


# 直接使用 Request 对象
# 假设要在路径操作函数中获取客户端 IP 地址和主机。
#
# 此时，需要直接访问请求。

from fastapi import FastAPI, Request

app = FastAPI()


@app.get("/items/{item_id}")
def read_root(item_id: str, request: Request):
    """
    路径操作函数的参数类型声明为 Request：

    1. 将路径操作函数的参数类型声明为 Request，FastAPI 就能把 Request 传递到参数里。

    2. 提取和验证路径参数：
       - 除了声明请求参数之外，还声明了路径参数。
       - 因此，能够提取、验证路径参数、并转换为指定类型，还可以用 OpenAPI 注释。

    3. 声明其他参数：
       - 可以正常声明其他参数，同时提取 Request 对象。
    """

    client_host = request.client.host

    return {"client_host": client_host, "item_id": item_id}